The heading
is designed to draw your attention.
Our timer has a number of preset times, similar to a microwave oven. By
pressing the appropriate button, the timer counts down and beeps when
the time has expired. A LED shows the associated time.
PHOTO OF CONNECTOR PICkit-2 is low-cost, easy-to-use and comes with full software on
CD's. It reads the chip "type-number" before programming and let's you
know if the chip is ready to program (such as excess voltage on the
chip from the project - turn OFF the project before programming the chip). LED MYTH There is a generally accepted thought that the voltage across a LED is a fairly constant value. But this is not so. As the current drops across it, the "characteristic voltage drop" also drops significantly. For the LEDs used in this project, the voltage drops form 2.3v (when full current is flowing) to 1.66v when less than 1mA flows. This value is important as we are placing 4 LEDs across a 5.4v supply and we need to know if any current will flow through the combination when the project is resting. In our case, the 4 LEDs require 6.64v This means no current will flow when the supply is 5.4v. To turn on the pair of LEDs for "1," GP1 is taken LOW. To turn on "2," GP1 is taken HIGH. To turn off both sets of LEDs, GP1 is made an input (high impedance). THE PROGRAM Using a microcontroller is like being handed a blank notebook. You can write a novel, a science report or create just about anything. The same with a microcontroller. The possibilities with a microcontroller as simple as the PIC12F629 are almost endless. The first thing to do is work out what requirements you need and see if they fit into the capabilities of the chip. The chip has 5 in-out lines and one INPUT-ONLY line (GP3, pin4). The next thing is how to read a number of buttons via a single line and how to illuminate more than one LED from a single line. You will also need to know how to produce tones, and sub-routines that are transparent, so the micro does not get "caught-up" in executing a particular routine. These things are covered in separate articles such as "Start Here with PIC12F629." PIC12F629 & PIC12F675 The two simplest 8-pin PIC chips are PIC12F629 and PIC12F675. These are identical except the PIC12F675 has four A-D channels and PIC12F629 has none. One of these channels could be used for the Button sub-routine, but we have used a slightly different method of detection using a standard input line, so either chip can be used in our project. PROGRAMMING IN ASSEMBLY LANGUAGE The program for this project has been created using the 35 instructions that are accepted by the microcontroller. This is called ASSEMBLY LANGUAGE and when you are creating a program in this way, you are programming in mnemonics. A mnemonic is a set of letters or numbers that can be read by a human and easily remembered by the programmer. For instance, "btfss 2C,3" represents the operation: "bit test 3 in file 2C and skip the next instruction if it is set." All the operations for our micro can be performed using about 35 instructions and these are very easy to remember. Each line of your program contains a single instruction and just before the micro is "burnt," a software program called an assembler is used to change the instructions into bytes that can be read by the micro. The assembler will produce "hex" bytes and create a file with the extension .hex The next piece of software you will use is called a Programmer and will take the .hex file and convert it to binary "1's" and "0's" for "burning" into the chip. This process is called "programming." Using mnemonics is called a low-level language because the instruction can be almost directly read by the micro. You can use higher-level languages (such as C) in which a single instruction will perform a more-complex task than one of our mnemonic instructions, but as you go further up the programming ladder you get further removed from actually understanding PIC language. Our intent is to show what can be done with a simple 8-pin PIC chip and how a program is written. We have made programming very simple by putting the 35 instructions in a list and sample programs are available on Talking Electronics website. By copying and pasting a sub-routine (or even a single instruction), you cannot make a mistake. Just keep to the same layout of each instruction and place them in the correct column (the layout of a program can be seen in Button sub-routine below). There are no syntax complications, like the order of placing brackets or understanding what symbols like: "/, ^, &&" mean and if you follow our guidelines of "copy and paste" and "make one alteration at a time," you will have success. MORE ON THE WEB This project is much more complex than meets the eye. There is a lot of detail available about using PIC chips, creating programs etc and these can be found on the web by simply Googling PIC12F629. The web is definitely the most incredible invention since "moveable type" and since it is the result of millions of individual contributors, you will find an enormous amount of assistance at: "PIC Micro Webring." In addition you will find information on "Talking Electronics Website." Click: "Fish Shop Timer" in the left index. TRANSPARENT SUB-ROUTINES Most of the routines provided in text books contain the relevant instructions for a particular operation. But none of them allow the sub-routine to be carried-out and the micro to return to the main routine. Some sample routines even include a loop in a button routine that prevents a return until the button has been released. Obviously this will hold up the operation of our timer is unsuitable. We need a sub-routine that is called and returns as soon as possible. This means it must carry out the operation and set a bit in a file - or clear a bit - (called a flag file) so the result can be operated on. We call this routine "transparent" because none of the registers (that are looked at) are altered and the result is kept in a flag file. We will be explaining these flag instructions later. In our case, the input buttons need to "polled" (looked at) regularly to identify if a button has been pressed. This can be done in a number of ways. The program can be designed so it goes to a location (address 04 in the program) called the Interrupt Location (or Interrupt Vector Location), on regular basis, such as every few milliseconds. At this address is an instruction that sends the micro to the sub-routine to look at the buttons. It will be a single instruction such as GOTO ISR (goto isr). That's why you don't start a program at address 0000 and continue through address 04, 05 etc as you may use "isr" and it needs location "04." At address 0000 place: goto Main. Leave 0001, 0002, 0003 empty and put "goto isr" at address 04. org 0x00 ;origin (in decimal) - reset vector address goto Main ;(this instruction will be at address 00) org 0x04 ;address 04 (in decimal) - Interrupt Vector address goto isr ;go to Interrupt Service Routine (this instruction will be at address 04) Again, the isr sub-routine needs to have a flag-file to identify which button has been pressed. Alternatively the MAIN routine can constantly scan the buttons. Or the micro can be set up to scan the buttons when it detects a button has be pressed. We will be using a feature where the operation of the micro is interrupted by a counter and it is sent to address 04. MULTI-TASKING The micro will be carrying out MULTI-TASKING in this project. It will be decrementing a number of files (the timing files) and at the same time checking to see if a button has been pressed. For this reason we need to set up the program so that these operations can be carried out. One thing we want to do is detect when a button has been pressed for 3 seconds. We cannot keep looping around a routine for 3 seconds as this will hold up the program from doing other operations, so we must have a file that is incremented while a button is pushed to identify the 3 seconds. The easiest way to do this is call the button routine every 15 milliseconds and when a file is incremented 200 times, the result will be 15 x 200 = 3 seconds. To do this we use one of the timers (Timer0) and get it to increment each time an instruction is carried out. We then set bits so that when the timer "ticks over" from FF to 00, the micro stops the current instruction and goes to address 04. At address 04, the micro executes the "goto" instruction. We call this instruction the ISR (Interrupt Service Routine). Timer0 can only count to 256, so we add a pre-scaler to the front end to divide the incoming clock-line by 64. This produces a result of 16,384uS (16.3mS). By incrementing another file 183 times we get 3 seconds. This covers two features. The button routine is scanned every 16mS and a 3-second button-press can be detected by incrementing a counter. The only other operation carried out in the "isr" section of the program is decrementing of 5 "timing files." These are ALL constantly decremented every second and when a file reaches 00, it is checked to see if the particular timing-button has been activated. If the timing has been activated, a beep will be produced for 10 seconds. In other words we have two routines that are constantly looped, Main and ISR. Main is looped every fraction of a millisecond and ISR is looped every 16 milliseconds. To put it more accurately: Main is looped on a constant basis and every 16 milliseconds the micro is sent to isr (address04) where it goes to the Button sub-routine. THE BUTTON ROUTINE We have opted for the simplest routine to detect a button-press. It uses in/out line GP0 (pin 7) and the routine firstly discharges the 220p capacitor then waits for it to charge to a point where the input line detects a HIGH. Even though we do not know the voltage level at which this occurs, it will be the same percentage value of the supply voltage in all cases. This will be fairly reliable over a small range of supply voltages as the input will detect a slightly lower voltage as the battery voltage reduces but the charging time will also alter to maintain the same timing. The circuit below shows the resistive ladder and the 5 buttons. The shortest time will occur when button 5 is pressed and the longest when no buttons are pressed. The timing for each of the buttons has been worked out experimentally and a mid-value has been provided in the routine. There will be a variation in the timing due to the value at which a micro turns on and its turn-on point due to the voltage of the supply, The exact timing will also depend on the tolerance of the resistors and especially the 220p as it will normally be 20%. The timing for each value is more than 20% apart and hopefully all the other tolerances will cancel each other and the result will fit into the values we have provided in the routine. From experimentation via the prototype, the timing for each of the buttons worked out as follows:
Two different types button-press must be
detected. A button-press of a short duration must be detected as well as
a button press of 3-seconds. A 3-second button-press is used to set a
button to the time indicated on the "pot." This makes it a lot more
complex than an ordinary button detection.
Button
Sub-routine: In the Equates section you will need to give a file to bflag and the two count files for Button:
You will need
to clear the button-flag in "SetUp"
In Main you will need to: Buttons sub-routine makes GP0 an output and goes
LOW to discharge the 220p. A short delay is called to do this.
|